package com.mugu.ipclient;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Panel;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.FileNotFoundException;
import java.util.Calendar;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;

public class UIIpclient implements ActionListener {

	private int TIME_TIMEOUT_FOR_RE_LOGIN = 4 * 1000;
	private final static String accsFileName = IPClientUtils.getProjectPath()
			+ "account.dat";
	private final static String WRONG_USERNAME_OR_PASSWORD = "用户名或密码错误";
	private final static String NOT_ENOUGH_MONEY = "您的钱不够了";
	private final static String NOT_RESPONSE = "服务器无响应";
	private Vector<Vector<String>> accList = new Vector<Vector<String>>();
	private int curMonth = Calendar.getInstance().get(Calendar.MONDAY) + 1;
	private int preAccIndex = -1;
	private int curAccIndex = 0;
	private IpClient mIpClient;

	private int popupSelectRow = -1;

	private JFrame jFrame = new JFrame("桂电出校器-by木鼓");;
	private JPanel topPanel;
	private JPanel bottomPanel;
	private JTable accsTable;

	private JButton startBn = new JButton("Start");
	private JButton stopBn = new JButton("Stop");
	private JButton refreshBn = new JButton("Refresh");
	private JButton addAccountBn = new JButton("Add Account");
	private JPopupMenu accsMenu;
	private JMenuItem openItem = new JMenuItem("Login");
	private JMenuItem deleteItem = new JMenuItem("Delete");

	private JLabel flowLbl = new JLabel("流量：");
	private JLabel moneyLbl = new JLabel("余额：");
	private JLabel msgLbl = new JLabel("Stop");
	private JLabel ipLbl = new JLabel();

	private DefaultTableModel accsTableModel;
	private String[] accsTitles = { "帐号", "密码", "余额", "备注" };

	private RefreshRunnable refreshRunnable;
	private BeginRunnable beginRunnable;

	public UIIpclient() {
		creatUI();
		mIpClient = new IpClient();
		try {
			ipLbl.setText(mIpClient.getNews());
		} catch (RefreshFaileException e) {
			msgLbl.setText(e.getMessage());
		}
	}

	public void creatUI() {
		initJFrame1();
		initTopPanel();
		initAccsTable();
		initBottomPanel();
		initJFrame2();
		// 监听程序退出，退出着保存数据
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				try {
					IPClientUtils.writeAccounts(accsFileName, accList);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
			}
		});
	}

	private void initJFrame1() {
		jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jFrame.setResizable(false);

		jFrame.setLayout(new BorderLayout(0, 5));

	}

	private void initJFrame2() {
		Toolkit tk = jFrame.getToolkit();// 得到窗口工具条
		Dimension dm = tk.getScreenSize();
		jFrame.pack();
		jFrame.setLocation(
				(int) (dm.getWidth() - jFrame.getSize().getWidth()) / 2,
				(int) (dm.getHeight() - jFrame.getSize().getHeight()) / 2);
		jFrame.setVisible(true);
	}

	private void initTopPanel() {

		topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10));
		topPanel.add(startBn);
		startBn.addActionListener(this);
		topPanel.add(stopBn);
		stopBn.addActionListener(this);
		topPanel.add(refreshBn);
		refreshBn.addActionListener(this);
		topPanel.add(addAccountBn);
		addAccountBn.addActionListener(this);
		jFrame.add(topPanel, BorderLayout.NORTH);

	}

	private void initAccsTable() {

		// 设置表格标题
		final Vector<String> title = new Vector<String>();
		for (String s : accsTitles) {
			title.add(s);
		}
		// 声明表格的数据model
		accsTableModel = new DefaultTableModel() {
			@Override
			public boolean isCellEditable(int row, int column) {
				return column != 2 && column != 3;
			}
		};
		accsTableModel.addTableModelListener(new TableModelListener() {

			@Override
			public void tableChanged(TableModelEvent e) {
				if (e.getType() == TableModelEvent.UPDATE) {
					if (e.getColumn() == 0 || e.getColumn() == 1) {
						accsTableModel.setValueAt("", e.getFirstRow(), 3);
					}
				}
			}
		});
		accsTable = new JTable(accsTableModel);
		// 多线程加载数据
		new Thread() {
			@Override
			public void run() {
				try {
					accList = IPClientUtils.loadAccounts(accsFileName);
					accsTableModel.setDataVector(accList, title);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.start();
		// 定义右键帐号列表事件
		accsMenu = new JPopupMenu();
		openItem.addActionListener(this);
		deleteItem.addActionListener(this);
		accsMenu.add(openItem);
		accsMenu.add(deleteItem);
		accsTable.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				if (e.isPopupTrigger()) {
					popupSelectRow = e.getY() / accsTable.getRowHeight();
					accsMenu.show(e.getComponent(), e.getX(), e.getY());
					accsTable.setRowSelectionInterval(popupSelectRow,
							popupSelectRow);
				}
			}
		});
		// 将表格添加到界面中
		jFrame.add(new JScrollPane(accsTable));
	}

	private void initBottomPanel() {

		bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 20));
		bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
		Panel flowPanel = new Panel(new FlowLayout(FlowLayout.LEFT, 20, 5));
		Panel moneyPanel = new Panel(new FlowLayout(FlowLayout.LEFT, 20, 5));
		Panel msgPanel = new Panel(new FlowLayout(FlowLayout.LEFT, 20, 5));
		Panel ipPanel = new Panel(new FlowLayout(FlowLayout.RIGHT, 20, 5));
		flowLbl.setMinimumSize(new Dimension(200, 0));
		moneyLbl.setMinimumSize(new Dimension(200, 0));
		msgLbl.setMinimumSize(new Dimension(200, 0));
		ipLbl.setMinimumSize(new Dimension(200, 0));
		flowPanel.add(flowLbl);
		moneyPanel.add(moneyLbl);
		msgPanel.add(msgLbl);
		ipPanel.add(ipLbl);
		bottomPanel.add(flowPanel);
		bottomPanel.add(moneyPanel);
		bottomPanel.add(msgPanel);
		bottomPanel.add(ipPanel);
		jFrame.add(bottomPanel, BorderLayout.SOUTH);
	}

	private class RefreshRunnable implements Runnable {
		private boolean isStop = false;

		public void stopRefresh() {
			isStop = true;
		}

		@Override
		public void run() {
			while (!isStop) {
				System.out.println(Thread.currentThread().getName());
				try {
					mIpClient.refreshOnline();
				} catch (RefreshFaileException e1) {
					if (preAccIndex < accsTableModel.getRowCount()
							&& preAccIndex >= 0) {
						accsTableModel.setValueAt("", preAccIndex, 3);
					}
					callBack(e1.getMessage());
					return;
				}
				invalidateFlowAndMoney();
				try {
					Thread.sleep(IpClient.TIME_REFRESH_ONLINE_INTERVAL);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	};

	private class BeginRunnable implements Runnable {
		private boolean isBeginRunnableStop = false;

		public void stopBegin() {
			isBeginRunnableStop = true;
		}

		@Override
		public void run() {
			Vector<String> curAccAry = null;
			double money;
			for (int i = curAccIndex; i < accList.size(); i++, curAccIndex++) {
				if (isBeginRunnableStop) {
					return;
				}
				curAccAry = accList.get(i);
				money = 5;
				try {
					String m = curAccAry.get(2).split("/")[1];
					m = m.split("元")[0];
					money = Double.parseDouble(m);
				} catch (Exception e) {
				}
				if (curAccAry.get(3).equals(WRONG_USERNAME_OR_PASSWORD)
						|| money < 0.01) {
					continue;
				}
				System.out.println(Thread.currentThread().getName());
				mIpClient.setUserInfo(curAccAry.get(0), curAccAry.get(1));
				try {
					msgLbl.setText(mIpClient.login());
					if (preAccIndex < accsTableModel.getRowCount()
							&& preAccIndex >= 0) {
						accsTableModel.setValueAt("", preAccIndex, 3);
					}
					accsTableModel.setValueAt("开放中...", curAccIndex, 3);
					invalidateFlowAndMoney();
					preAccIndex = curAccIndex;
					accsTable.invalidate();
					refreshOnlineInterval();
					return;
				} catch (LoginFaileException e) {
					if (preAccIndex < accsTableModel.getRowCount()
							&& preAccIndex >= 0) {
						accsTableModel.setValueAt("", preAccIndex, 3);
					}
					accsTable.invalidate();
					if (!isBeginRunnableStop) {
						callBack(e.getMessage());
					}
				}
			}
			UIStop();
			msgLbl.setText("帐号已用完！");
			curAccIndex = 0;
		}
	};

	public void begin() {
		if (beginRunnable != null) {
			beginRunnable.stopBegin();
			curAccIndex++;
		}
		beginRunnable = new BeginRunnable();
		new Thread(beginRunnable).start();
	}

	public void callBack(String msg) {
		System.err.println(msg);
		mIpClient.setLogin(false);
		flowLbl.setText("流量：");
		moneyLbl.setText("余额：");
		msgLbl.setText(msg);
		if (msg.equals(WRONG_USERNAME_OR_PASSWORD)) {
			accList.get(curAccIndex).set(3, WRONG_USERNAME_OR_PASSWORD);
			accsTableModel.fireTableDataChanged();
			accsTable.invalidate();
		} else if (msg.equals(NOT_ENOUGH_MONEY)) {
			accList.get(curAccIndex).set(3, NOT_ENOUGH_MONEY);
			accList.get(curAccIndex).set(2,
					String.format("%d月/%.2f元", curMonth, 0.0));
			accsTableModel.fireTableDataChanged();
			accsTable.invalidate();
		} else if (msg.equals(NOT_RESPONSE)) {
			if (refreshRunnable != null) {
				refreshRunnable.stopRefresh();
			}
			accList.get(curAccIndex).set(3, NOT_RESPONSE);
			accsTableModel.fireTableDataChanged();
			accsTable.invalidate();
			try {
				Thread.sleep(TIME_TIMEOUT_FOR_RE_LOGIN);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			curAccIndex--;
		}
	}

	public void refreshOnlineInterval() {
		if (refreshRunnable != null) {
			refreshRunnable.stopRefresh();
		}
		refreshRunnable = new RefreshRunnable();
		new Thread(refreshRunnable).start();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource().equals(openItem)) {
			curAccIndex = popupSelectRow - 1;
			begin();
		} else if (e.getSource().equals(deleteItem)) {
			accsTableModel.removeRow(popupSelectRow);
			accsTable.invalidate();
		} else if (e.getSource().equals(startBn)) {
			begin();
		} else if (e.getSource().equals(stopBn)) {
			UIStop();
		} else if (e.getSource().equals(refreshBn)) {
			UIRefreshOnline();
		} else if (e.getSource().equals(addAccountBn)) {
			String[] data = { "*帐号*", "*密码*", "", "" };
			accsTableModel.addRow(data);
			accsTable.invalidate();
		}
	}

	private void UIRefreshOnline() {
		new Thread() {
			@Override
			public void run() {
				try {
					mIpClient.refreshOnline();
					invalidateFlowAndMoney();
				} catch (RefreshFaileException e1) {
					msgLbl.setText(e1.getMessage());
				}
			}
		}.start();
	}

	private void UIStop() {
		new Thread() {
			@Override
			public void run() {
				try {
					if (mIpClient.isLogin()) {
						msgLbl.setText(mIpClient.logout());
						if (preAccIndex < accsTableModel.getRowCount()
								&& preAccIndex >= 0) {
							accsTableModel.setValueAt("", preAccIndex, 3);
							accsTableModel.setValueAt("", curAccIndex, 3);
						}
					}
				} catch (LogoutFaileException e1) {
					msgLbl.setText(e1.getMessage());
				}
			}
		}.start();
		flowLbl.setText("流量：");
		moneyLbl.setText("余额：");
		msgLbl.setText("Stop");
		if (beginRunnable != null) {
			beginRunnable.stopBegin();
			beginRunnable = null;
		}
		if (refreshRunnable != null) {
			refreshRunnable.stopRefresh();
			refreshRunnable = null;
		}
	}

	private void invalidateFlowAndMoney() {
		try {

			if (mIpClient.getFlow() / 1024 / 1024 >= 1) {
				flowLbl.setText(String.format("流量：%.3fMb",
						mIpClient.getFlow() / 1024 / 1024));
			} else {
				flowLbl.setText(String.format("流量：%.3fKb",
						mIpClient.getFlow() / 1024));
			}
			moneyLbl.setText(String.format("余额：%.2f元", mIpClient.getMoney()));
			accList.get(curAccIndex).set(2,
					String.format("%d月/%.2f元", curMonth, mIpClient.getMoney()));
			accsTableModel.fireTableDataChanged();
			accsTable.invalidate();

			System.out.println("流量：" + mIpClient.getFlow() + "b   余额："
					+ mIpClient.getMoney() + "元");
		} catch (Exception e) {
		}
	}
}
